home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 December: Technology Seed / ATS Dec. '97.toast / Navigation Services SDK 1.0b1 / Examples / SimpleText / SimpleText ƒ / NavigationServicesSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-20  |  7.7 KB  |  343 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        NavigationServicesSupport.c
  3.  
  4.     Contains:    <contents>
  5.  
  6.     Written by:    Sean Findley
  7.  
  8.     Copyright:    <copyright>
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <21>     11/5/97    KLM        App name in window title
  13.         <20>     11/4/97    KLM        App name in dialog titles
  14.         <19>    10/20/97    KLM        more a6 interface changes
  15.         <18>    10/13/97    KLM        a6 interface changes
  16.         <17>    /19/1997    Yan        Mixed mode support
  17.         <15>     5/23/97    sjf     
  18. */
  19.  
  20.  
  21. /*
  22.     File:        NavigationServicesSupport.c
  23.  
  24.     Contains:    xxx put contents here xxx
  25.  
  26.     Version:    xxx put the technology version here xxx
  27.  
  28.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  29.  
  30.     File Ownership:
  31.  
  32.         DRI:                Yan Arrouye
  33.  
  34.         Other Contact:        xxx put alternate contact (owner’s functional manager) here xxx
  35.  
  36.         Technology:            xxx put the technology group name here xxx
  37.  
  38.     Writers:
  39.  
  40.         (KLM)    Keith Mortensen
  41.         (Yan)    Yan Arrouye
  42.  
  43.     Change History (most recent first):
  44.  
  45.         <14>     5/15/97    Yan        Updated for new API
  46.         <13>     5/08/97    KLM        Fixed NewOpenHandle bug, it was never creating a open rsrc.
  47.         <12>     5/08/97    Yan        Use isStationery flag
  48.         <11>     4/21/97    Yan        
  49.         <10>     4/21/97    Yan        NavGetDefaultDialogsOptions really
  50.          <9>     4/21/97    Yan        Use new NavSetDefaultDialogsOptions
  51.          <8>     4/21/97    Yan        Implemented isStationery in save
  52.          <7>     4/21/97    Yan        Updated for latest include
  53.          <6>     4/18/97    Yan        Rev'ed for new API
  54.          <5>     4/14/97    Yan        Added a NULL version of this file for classic 68K runtime (not
  55.                                     supported)
  56. */
  57.  
  58. #include "NavigationServicesSupport.h"
  59.  
  60.  
  61.  
  62. #include <CodeFragments.h>
  63. #include <Finder.h>
  64. #include <Dialogs.h>
  65. #include <LowMem.h>
  66. #include <string.h>
  67.  
  68.  
  69.  
  70.  
  71.  
  72. static Handle NewOpenHandle(OSType applicationSignature, short numTypes, OSType typeList[])
  73. {
  74.     Handle hdl = NULL;
  75.     
  76.     if ( numTypes > 0 )
  77.     {
  78.     
  79.         hdl = NewHandle(sizeof(NavTypeList) + numTypes * sizeof(OSType));
  80.     
  81.         if ( hdl != NULL )
  82.         {
  83.             NavTypeListHandle open        = (NavTypeListHandle)hdl;
  84.             
  85.             (*open)->componentSignature = applicationSignature;
  86.             (*open)->osTypeCount        = numTypes;
  87.             BlockMoveData(typeList, (*open)->osType, numTypes * sizeof(OSType));
  88.         }
  89.     }
  90.     
  91.     return hdl;
  92. }
  93.  
  94.  
  95.  
  96.  
  97. static OSStatus SendOpenAE(AEDescList list)
  98. {
  99.     OSStatus        err;
  100.     AEAddressDesc    theAddress;
  101.     AppleEvent        dummyReply;
  102.     AppleEvent        theEvent;
  103.     
  104.     theAddress.descriptorType    = typeNull;
  105.     theAddress.dataHandle        = NULL;
  106.  
  107.     do {
  108.         ProcessSerialNumber psn;
  109.     
  110.         err = GetCurrentProcess(&psn);
  111.         if ( err != noErr) break;
  112.         
  113.         err =AECreateDesc(typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber), &theAddress);
  114.         if ( err != noErr) break;
  115.             
  116.         dummyReply.descriptorType    = typeNull;
  117.         dummyReply.dataHandle        = NULL;
  118.  
  119.         err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &theAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  120.         if ( err != noErr) break;
  121.         
  122.         err = AEPutParamDesc(&theEvent, keyDirectObject, &list);
  123.         if ( err != noErr) break;
  124.         
  125.         err = AESend(&theEvent, &dummyReply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  126.         if ( err != noErr) break;
  127.         
  128.             
  129.     } while (false);
  130.     
  131.     return err;
  132. }
  133.  
  134.  
  135.  
  136. OSStatus OpenFileDialog(OSType applicationSignature, short numTypes, OSType typeList[], NavEventProcPtr eventProc, FSSpec* fileSpec, OSType* fileType)
  137. {
  138.     NavReplyRecord        theReply;
  139.     NavDialogOptions    dialogOptions;
  140.     OSErr                theErr        = noErr;
  141.     NavTypeListHandle    openList    = NULL;
  142.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  143.  
  144.     NavGetDefaultDialogOptions(&dialogOptions);
  145.  
  146.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  147.     
  148.     openList = (NavTypeListHandle)NewOpenHandle(applicationSignature, numTypes, typeList);
  149.     if ( openList )
  150.     {
  151.         HLock((Handle)openList);
  152.     }
  153.     
  154.     theErr = NavGetFile(NULL, &theReply, &dialogOptions, eventUPP, NULL, NULL, openList, NULL);
  155.     DisposeRoutineDescriptor(eventUPP);
  156.     
  157.     if (theReply.validRecord)
  158.     {
  159.         // grab the target FSSpec from the AEDesc for opening:    
  160.         AEDesc     resultDesc;
  161.         FInfo    fileInfo;
  162.  
  163.         // Is this a single file open
  164.         if ( fileSpec != NULL )
  165.         {
  166.             AEKeyword keyword;
  167.             
  168.             theErr = AEGetNthDesc(&theReply.selection, 1, typeFSS, &keyword, &resultDesc);
  169.             if (theErr == noErr)
  170.                 BlockMove(*resultDesc.dataHandle,fileSpec,sizeof(FSSpec));
  171.                 
  172.             // decide if the doc we fileSpec opening is a PICT or TEXT
  173.             theErr = FSpGetFInfo(fileSpec, &fileInfo);
  174.             if (theErr == noErr)
  175.             {
  176.                 if ( fileType != NULL )
  177.                     *fileType = fileInfo.fdType;
  178.             }
  179.         }
  180.         else
  181.         {
  182.             // Multiple files open: use ApleEvents
  183.             theErr = SendOpenAE(theReply.selection);
  184.         }
  185.  
  186.         NavDisposeReply(&theReply);
  187.     }
  188.     else
  189.     {
  190.         theErr = userCanceledErr;
  191.     }
  192.  
  193.     if (openList != NULL)
  194.     {
  195.         HUnlock((Handle)openList);
  196.         DisposeHandle((Handle)openList);
  197.     }
  198.     
  199.     return theErr;
  200. }
  201.  
  202.  
  203. short ConfirmSaveDialog(StringPtr documentName, Boolean quitting, NavEventProcPtr eventProc)
  204. {
  205.     OSStatus                theStatusErr     = noErr;
  206.     OSErr                     theErr             = noErr;
  207.     NavAskSaveChangesResult    reply             = 0;
  208.     NavAskSaveChangesAction    action             = 0;
  209.     NavEventUPP                eventUPP        = NewNavEventProc(eventProc);
  210.     NavDialogOptions        dialogOptions;
  211.     short                    result;
  212.     
  213.     if (quitting)
  214.         action = kNavSaveChangesQuittingApplication;
  215.     else
  216.         action = kNavSaveChangesClosingDocument;
  217.         
  218.     BlockMoveData(LMGetCurApName(),dialogOptions.clientName,LMGetCurApName()[0]+1);
  219.     BlockMoveData(documentName,dialogOptions.savedFileName,documentName[0]+1);
  220.     
  221.     theErr = NavAskSaveChanges(    &dialogOptions,
  222.                                 action,
  223.                                 &reply,
  224.                                 eventUPP,
  225.                                 NULL);
  226.     DisposeRoutineDescriptor(eventUPP);
  227.     
  228.     // Map reply code to ok, cancel, dontSave
  229.     switch (reply)
  230.     {
  231.         case askSaveChangesSave:
  232.             result = ok;
  233.             break;
  234.             
  235.         case askSaveChangesCancel:
  236.             result = cancel;
  237.             break;
  238.             
  239.         case askSaveChangesDontSave:
  240.             result = dontSaveChanges;
  241.             break;
  242.     }
  243.     
  244.     return result;
  245. }
  246.  
  247.  
  248.  
  249. OSStatus SaveFileDialog(StringPtr fileName, OSType filetype, OSType fileCreator, 
  250.                         NavEventProcPtr eventProc, FSSpec* fileSpec, 
  251.                         Boolean* stationery, Boolean* replacing, NavReplyRecord* reply)
  252. {
  253.     NavDialogOptions    dialogOptions;
  254.     OSErr                theErr        = noErr;
  255.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  256.  
  257.     NavGetDefaultDialogOptions(&dialogOptions);
  258.  
  259.     dialogOptions.dialogOptionFlags |= (stationery != NULL ? kAllowStationery : 0);
  260.     BlockMoveData(fileName, dialogOptions.savedFileName, fileName[0] + 1);
  261.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  262.  
  263.     theErr = NavPutFile(NULL, reply, &dialogOptions, eventUPP, filetype, fileCreator, NULL);
  264.     DisposeRoutineDescriptor(eventUPP);
  265.     
  266.     if (reply->validRecord)
  267.     {
  268.         // User saved
  269.         AEDesc     resultDesc;
  270.         AEKeyword keyword;
  271.             
  272.         // retrieve the returned selection:
  273.         theErr = AEGetNthDesc(&reply->selection, 1, typeFSS, &keyword, &resultDesc);
  274.         if (theErr == noErr)
  275.             BlockMove(*resultDesc.dataHandle, fileSpec, sizeof(FSSpec));
  276.  
  277.         if ( replacing != NULL )
  278.             *replacing = reply->replacing;
  279.         
  280.         if ( stationery != NULL )
  281.         {
  282.             *stationery    = reply->isStationery;
  283.         }
  284.     }
  285.     else
  286.     {
  287.         // User cancelled
  288.         if ( replacing != NULL )
  289.             *replacing = false;
  290.         
  291.         if ( stationery != NULL )
  292.             *stationery    = false;    
  293.  
  294.         theErr = userCanceledErr;
  295.     }
  296.     
  297.     return theErr;
  298. }
  299.  
  300.  
  301.  
  302. OSStatus CompleteSave(const FSSpec*, NavReplyRecord* reply)
  303. {
  304.     OSStatus theErr;
  305.     
  306.     if (reply->validRecord)
  307.     {
  308.         theErr = NavCompleteSave(reply, kNavTranslateInPlace);
  309.     }
  310.  
  311.     theErr = NavDisposeReply(reply);
  312.     
  313.     return theErr;
  314. }
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322. //
  323. // Callback to handle events that occur while navigation dialogs are up but really should be handled by the application
  324. //
  325.  
  326. extern void HandleEvent(EventRecord * pEvent);
  327.  
  328.  
  329. pascal void MyEventProc(const NavEventCallbackMessage callBackSelector, 
  330.                         NavCBRecPtr callBackParms, 
  331.                         NavCallBackUserData /*callBackUD*/)
  332. // Callback to handle event passing betwwn the navigation dialogs and the applicatio
  333. {
  334.     if ( callBackSelector == kNavCBEvent )
  335.         switch (callBackParms->eventData.event->what)
  336.         {
  337.             case updateEvt:
  338.                 HandleEvent(callBackParms->eventData.event);
  339.                 break;
  340.         }
  341. }
  342.  
  343.